﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using GameLib.Utils;
using Sandbox.Scene.Elements;
using Sandbox.Scene;
using System.Windows.Media;
using GameLib.Utils.Pathing;
using Sandbox.Editor.Helpers;
using GameLib;
using GameLib.WorldMap;

namespace Sandbox.Editor.Modes
{
	public class RiverMode : EditorMode
	{
		public RiverMode(EditorWindow window)
			: base(window)
		{
			m_RiverNodeSemantics = new RiverNodeSemantics();
			m_PathFinder = new PathFinder<MapVertex>(m_RiverNodeSemantics);
		}

		public override void MapWindow_MouseLeftButtonDown(MouseButtonEventArgs e)
		{
			base.MapWindow_MouseLeftButtonDown(e);

			if (MouseOverVertex.HasValue)
			{
				if (IsPaintingRiver)
				{
					if (MouseOverVertex == LastVertex)
						EndPaintRiver();
					else
						PaintRiver();
				}
				else
				{
					StartPaintRiver();
				}
			}			
		}

		public override void MapWindow_MouseMove(MouseEventArgs e)
		{
			base.MapWindow_MouseMove(e);

			ShowVertexCursor(e);
		}

		public override void MapWindow_GainFocus(MouseEventArgs e)
		{
			base.MapWindow_GainFocus(e);
			ShowVertexCursor(e);
		}

		public override void MapWindow_LoseFocus(MouseEventArgs e)
		{
			base.MapWindow_LoseFocus(e);
			HideVertexCursor();
		}

		private MapVertex? MouseOverVertex
		{
			get { return m_MouseOverVertex; }
		}

		private bool IsPaintingRiver
		{
			get { return m_LastVertex.HasValue; }
		}

		private MapVertex? LastVertex
		{
			get { return m_LastVertex; }
			set
			{
				if (m_LastVertex != value)
				{
					m_LastVertex = value;
					if (m_LastVertex.HasValue)
						ShowLastVertIndicator();
					else
						HideLastVertIndicator();
				}
			}
		}

		private void StartPaintRiver()
		{
			LastVertex = MouseOverVertex;
		}

		private void PaintRiver()
		{
			m_RiverNodeSemantics.MapScene = MapScene;
			if (m_PathFinder.SearchPath(LastVertex.Value, MouseOverVertex.Value))
			{
				if (m_River == null)
				{
					m_River = new River();
					m_River.Width = 5.0f;
					MapScene.Map.AddRiver(m_River);
					m_River.Extend(m_PathFinder.FoundPath);
				}
				else
				{
					m_River.Extend(m_PathFinder.FoundPathNoStart);
				}

				LastVertex = MouseOverVertex;
			}
		}

		private void EndPaintRiver()
		{
			m_River = null;
			LastVertex = null;
		}

		private void ShowVertexCursor(MouseEventArgs e)
		{
			MapVertex? vertLoc = Window.MapScene.GetVertexAt(e.GetPosition(Window.MapWindow));

			if (m_VertCursor == null)
			{
				m_VertCursor = new MapVertexCursor();
				Window.MapScene.AddSceneObject(m_VertCursor);
			}
			m_VertCursor.Vertex = vertLoc;
			m_VertCursor.Show();

			m_MouseOverVertex = vertLoc;
		}

		private void HideVertexCursor()
		{
			if (m_VertCursor != null)
				m_VertCursor.Hide();
		}

		private void ShowLastVertIndicator()
		{
			if (!LastVertex.HasValue)
				return;

			if (m_LastVertIndicator == null)
			{
				m_LastVertIndicator = new MapVertexCursor();
				m_LastVertIndicator.CursorColor = Colors.Blue;
				Window.MapScene.AddSceneObject(m_LastVertIndicator);
			}

			m_LastVertIndicator.Vertex = LastVertex;
			m_LastVertIndicator.Show();
		}

		private void HideLastVertIndicator()
		{
			if (m_LastVertIndicator != null)
				m_LastVertIndicator.Hide();
		}

		private MapVertexCursor m_VertCursor;
		private MapVertexCursor m_LastVertIndicator;
		private MapVertex? m_MouseOverVertex;
		private MapVertex? m_LastVertex;
		private River m_River;
		private PathFinder<MapVertex> m_PathFinder;
		private RiverNodeSemantics m_RiverNodeSemantics;

		
	}
}
